Customization Checklist for GenDS: Dosadi Generic TWAIN DataSource
Revision 3, 2001.09.25
BETA VERSION 1.01
This is a checklist for the task of specializing the GenDS generic DataSource to a specific device or device family. The steps are abbreviated – more details can be found in the source code, and in the Developer Notes for GenDS.
1. Initial Setup
1.1. Prerequisites:
1.1.1. Install this toolkit (I guess you’ve done that…)
1.1.2. Install Microsoft Visual C++, Version 6.0 or better.
1.1.3.
Install TWAIN DataSource Manager (DSM).
See the TWAIN Working Group website (www.twain.org) for the latest
distributable binaries and installation instructions.
1.1.4.
If you are working on Windows NT or 2000, update the
Windows directory.
In the Visual Studio, go to Project – Settings, and choose the Link
tab. Change the output directory, for
both Release and Debug configuration, from “Windows” to “winnt”.
1.1.5. Do a Rebuild All – there should be no errors.
1.1.6.
Test basic functionality
Run any TWAIN-aware application. Select
the “Generic DataSource” as the current source, and acquire some images. Under Win9x, Kodak Imaging is usually hidden
somewhere on your system, either in Start - Programs – Accessories, or as
KODAKIMG.EXE in the Windows directory.
2. Rename the DS
1.1.
Update the name and destination of the .DS file.
Go to the Project - Settings dialog,
under the Link tab. Change the name of
the final executable file from GenDS.ds to whatever you want. Remember to change both Debug and Release
configurations. DataSources are
installed under the TWAIN32 folder, in the Windows directory. We recommend you follow common practice and
put your files into a subfolder, for example
“TWAIN32\QuickCam” (Logitech video camera family) or “TWAIN32\fujidsc”
(Fuji Digital Still Camera).
1.2.
Update the TWAIN Identity strings
In Resources, in the string table, edit the Source identity strings to your
satisfaction. Note that the Product
Name is the string that appears in the TWAIN Select Source dialog, so it
should be chosen to make it easy for a naive user to recognize and select your
device. Note: Most of these strings are
limited to 32 characters by TWAIN. As
far as I know, the Product Family string is not used by anybody for
anything, and is never user visible - but I could be wrong. The
IDS_DS_COPYRIGHT string is not part of the TWAIN identity – it appears in the
default About box.
2. Bring up core device functionality: CMyDevice
2.1.
CMyDevice::Open
This is normally the next CMyDevice method called, after the constructor. It is called when the application opens your
DS and asks it to move to TWAIN State 4.
You should establish communication with your device. Do not return false if your device is
off-line! Just set a flag and continue
as best you can. Don’t worry about
settings yet, just establish enough communication to allow image acquisition.
2.2.
CMyDevice::IsDeviceOnline
This should be pretty straightforward.
This method is called when the application does a MSG_GET on
CAP_DEVICEONLINE in State 4. Most
applications won’t query this, so you will have to use a TWAIN testing utility
like Dosadi’s TWIRL (www.dosadi.com/twirl.htm)
to test your implementation.
2.3.
CMyDevice::PendingCount
As a first cut, you can just have this return –1 – but if you are ready, go
ahead and do the real implementation for your device. See the comments in the code.
2.4.
CMyDevice::GetDib or CMyDevice::GetBuffer
Implement one of these to transfer data from your device to TWAIN.
2.5. Initial Trial AKA “The Smoke Test”
2.5.1. Build and verify that your .DS file is there under <windows>\TWAIN_32\<yourfolder>
2.5.2. Fire up Kodak Imaging, Adobe Photoshop, Paint Shop Pro, or some other TWAIN application – select your DataSource, and do an Acquire.
2.5.3.
Debug
In Visual Studio, select the Win32 Debug configuration.
Go to Project – Settings, select the Debug tab.
In Executable for debug session: enter the full path & name of your
imaging test application e.g. “c:\windows\kodakimg.exe”.
Rebuild your DS if necessary, and do ‘Go’ (F5 with my setup, or Build –
Start Debug – Go)
You can breakpoint the CMyDevice methods that you have implemented, and follow
them to see what’s going wrong.
3. Expand the Settings / Capabilities
3.1. Look through the capabilities listed in Settings.h, and the partial list in the constructor for CMySettings, and decide which additional capabilities your device should support. You will have to get guidance from the TWAIN specification on the meaning and intent of specific capabilities.
3.2. For standard capabilities, you can normally ‘turn them on’ just be making a call to EnableCap in the constructor for CMySettings. If you need a standard capability that is not supported by CSettings, contact Dosadi and we’ll add it. If you add a capability that does not have a TWAIN-specified default (reset) value, you will need to add that cap as a case in an override of GetResetValue. If you need the capability to have a different set of valid values than the GenDS default, you will need to add the cap as a case in an override of GetValidValues.
3.3. In CMyDevice::StartScan / or CMyDevice::ConfigureDevice, get the values of your new capabilities from the settings object, and pass the settings on to your device / driver.
4. Update the UI
4.1.
Edit Dialog Templates
Edit the Dialog templates for IDD_MAIN_DIALOG and IDD_ABOUT to suit your needs,
and use the ClassWizard to create corresponding code.
4.2.
Customize CMyDialog::OnInitDialog
Here you configure and initialize your dialog based on the current device
settings – we recommend that you access the standard capabilities through the
CSettings interface. If your device has
parameters or properties, outside the scope of the TWAIN capabilities, that
need to be queried or set through the dialog, we recommend that you add support
for them to CMySettings in a style consistent with CSettings. An example of this would be the set of
photos in a Digital Still Camera – including a way of marking which ones have
been selected by the user for download / transfer.
Please note that while many capabilities have TWAIN-specified initial values,
once your dialog is displayed all bets are off – you are free to set these
capabilities to any value, by ‘authority of the user.’ Better do your homework though – your DS has
to still work when the dialog is not displayed – and then those capabilities must
have their TWAIN-specified initial values.
If a capability has no TWAIN-specified initial value, you are free in your
OnInitDialog to restore it to the last setting chosen by the user. The framework doesn’t give you any special
help, but the local ds object inherits the CWinApp methods for storing and
retrieving data in the Registry. There
is code in MyDialog.cpp showing how to do this with PixelType (ICAP_PIXELTYPE).
4.3. Pass settings from CMyDialog back to the CSettings object
4.3.1.
Alternative 1: Track user changes in real-time.
This can be done by attaching event handlers to your dialog controls. For example, you can attach a BN_CLICKED
handler to a radio button. There is
code demonstrating this method with the IDC_PIXELTYPE listbox, and the
IDC_LP_REFL (“Reflective Media”) radio button, in the original MyDialog.cpp.
4.3.2.
Alternative 2: Collect settings when user says “Go”.
This can be done by associating your dialog controls to value variables using
the ClassWizard, and calling UpdateData() in the OnOK handler. This extracts the current settings of all
those controls and updates the value of the associated variable. Then you walk through those variables and
pass their values to CSettings / CMySettings methods.
5. Implement Advanced features
5.1.
Image Layout
TWAIN allows the application to specify a “Region of Interest” i.e. a rectangle
smaller than the full scan size. If
your device / driver can digitize a sub-rectangle, as is the case with most
flatbeds, then you can read the current rectangle by using the CSettings::Frame
method – this returns a CFrame object, which specifies a Left, Top, Right and
Bottom coordinate in one of the TWAIN units: UN_INCHES, UN_CENTIMETERS,
UN_PIXELS, etc:
CFrame frame = MySettings()->Frame();
Probably you will want to know the frame coordinates in pixels, at the current
resolution setting, and to get that you just convert the frame:
frame.ConvertTo(UN_PIXELS);
If the frame was already specified in pixels, this does nothing. Clip the coordinates to safe values and pass
them to your device / driver.
5.2.
Automatic Document Feeder
There are a number of methods related to support of an automatic document
feeder (ADF) if you have one. See the
comments on CSettings::EnableADF, in settings.h as well as in the constructor
for CMySettings. Turning on ADF
features means that several virtual methods in CGenDevice become active, and
they may need to be overridden in CMyDevice.
These are commented in gendevice.h.